/**
 * 
 */
package org.istt.export;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import javax.servlet.ServletContext;

import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.util.TextProviderHelper;
import org.istt.domain.SubCategory;
import org.istt.model.FileBean;
import org.istt.web.WebConstants;
import org.joda.time.DateTime;

import com.opensymphony.xwork2.ActionContext;

/**
 * @author Huy
 *
 */
public abstract class BaseReport {
	static int FONT_SIZE_11 = 11;
	static int FONT_SIZE_12 = 12;
	static int FONT_SIZE_8 = 8;
	static int FONT_SIZE_10 = 10;
	static int SPACING_06 = 120;
	static int SPACING_0 = 0;
	static String FONT_TIMES_NEW_ROMAN = "Times New Roman";
	static ParagraphAlignment CENTER_ALIGN = ParagraphAlignment.CENTER;
	static ParagraphAlignment LEFT_ALIGN = ParagraphAlignment.LEFT;
	
	protected InputStream getFile(String path) throws IOException {
		ServletContext servletContext = ServletActionContext.getServletContext();
	    return new FileInputStream(new File(servletContext.getRealPath(path)));
	}
	
	protected String getText(String strKey){
		return TextProviderHelper.getText(strKey, "", ActionContext.getContext().getValueStack());
	}
	
	protected String getSubCategoryName(SubCategory subCategory){
		String result = "";
        if(subCategory!=null) result = "("+subCategory.getName()+")";
        
        return result;
	}
	
	public static float Round(float Rval, int Rpl) {
		  float p = (float)Math.pow(10,Rpl);
		  Rval = Rval * p;
		  float tmp = Math.round(Rval);
		  return (float)tmp/p;
	  }
	
	protected String getReturnDate(String strDate, String strDay){
		
		String result = " Ng\u00E0y "
		+ strDate.substring(8, 10)
		+ " th\u00E1ng "
		+ strDate.substring(5, 7)
		+ " n\u0103m "
		+ strDate.substring(0, 4)
		+ ", " + strDay;
		
		return result;
	}
	
	protected void setAlignment(XWPFParagraph paragraphObj, ParagraphAlignment alignment, int spacingAfter, int spacingBefore){
		paragraphObj.setAlignment(alignment);
        paragraphObj.setSpacingAfter(spacingAfter);
        paragraphObj.setSpacingBefore(spacingBefore);
	}
	
	protected void setTextFormat(XWPFRun run, String textValue, int fontSize, boolean bold, boolean italic , String fontName){
		run.setText(textValue);
		run.setFontSize(fontSize);
		run.setBold(bold);
		run.setFontFamily(fontName); 
		run.setItalic(italic);
	}
	
	
	/**
	 * Tinh toan va tra ve ket qua xu ly ho so. Cho biet thong tin xu ly ho so:
	 * - Dung han
	 * - Qua han
	 * - Con han
	 * ...
	 * @param objFile
	 * @param fromDate
	 * @param toDate
	 * @param weekends
	 * @param holidays
	 * @return
	 */
	public FileBean getResultOfFile(org.istt.domain.File file, Date fromDate, Date toDate, List<Integer> weekends,List<Date> holidays){
		FileBean result = null;
		int processTime = 0;
		Date receivedDate = file.getInputDate().toDate();
		Date outputDate = file.getOutputDate().toDate();
		String categoryName = file.getCategory().getCategoryName();
		
		DateTime completedDate = file.getDateCompleted();
		
		//Tinh toan thoi gian xu ly ho so theo ngay hen tra
		processTime = getWorkingDays(receivedDate, outputDate,weekends,holidays);
		
		// Cap nhat Ho ten nguoi tiep nhan ho so
//		User createdBy = userManager.get(file.getCreatedBy().getId());
//		file.setCreatedBy(createdBy);
		
		// CASE 1: HO SO XU LY XONG
		if(completedDate!=null && receivedDate!=null){
			
			// Tinh toan thoi gian thuc xu ly ho so, tinh den ngay xu ly xong
			int realTime = getWorkingDays(receivedDate, completedDate.toDate(), weekends, holidays);
			
			// Thoi gian chenh lech giua Ngay hen va Ngay thuc te
			int overtime = realTime - processTime;
			
			// Xu ly dung han
			if(realTime == processTime || realTime < processTime){
				
				result = new FileBean(file,getText("reportByDepartment.excel.table.content.DH"),getText("reportByDepartment.excel.table.content.note.DH"),categoryName);
								
			}
			// Xu ly qua han
			else if(realTime > processTime){
					String processResult = "";
					String noteResult = "";
					
					if(overtime <= WebConstants.FIVE){
						processResult = getText("reportByDepartment.excel.table.content.T5");
						noteResult = getText("reportByDepartment.excel.table.content.note.QH");
					}
					else if(overtime > WebConstants.FIVE && overtime <=WebConstants.TEN){
						processResult = getText("reportByDepartment.excel.table.content.T10");
						noteResult = getText("reportByDepartment.excel.table.content.note.QH");
					}
					else if(overtime > WebConstants.TEN && overtime <=WebConstants.TWENTY){
						processResult = getText("reportByDepartment.excel.table.content.T20");
						noteResult = getText("reportByDepartment.excel.table.content.note.QH");
					}
					else if(overtime > WebConstants.TWENTY ){
						processResult = getText("reportByDepartment.excel.table.content.T30");
						noteResult = getText("reportByDepartment.excel.table.content.note.QH");
					}
					
				result = new FileBean(file, processResult, noteResult, categoryName);
			}
		}
		// CASE 2: Ho so chua xu ly xong
		else if(completedDate == null){
			int realTime = getWorkingDays(receivedDate, toDate, weekends, holidays);
			
			if(processTime <= realTime){
				
				result = new FileBean(file,getText("reportByDepartment.excel.table.content.QH"),getText("reportByDepartment.excel.table.content.note.QH"),categoryName);
				
			}else 
				if(processTime > realTime){
					result = new FileBean(file,getText("reportByDepartment.excel.table.content.CH"),getText("reportByDepartment.excel.table.content.note.CH"),categoryName);
			}
		}
		
		return result;
	}
	
	
	/***
	 * Calculate number of working day between two dates without weekend
	 * @param startDt
	 * @param endDt
	 * @return number of working day
	 */
	public int getWorkingDays(Date startDt, Date endDt, List<Integer> weekend,List<Date> holiday) {
		Calendar startCal, endCal;
		startCal = Calendar.getInstance();
		startCal.setTime(startDt);
		endCal = Calendar.getInstance();
		endCal.setTime(endDt);
		int workDays = 0;

		// Return 0 if start and end are the same
		if (startCal.getTimeInMillis() == endCal.getTimeInMillis()) {
			return 0;
		}
		// Just in case the dates were transposed this prevents infinite loop
		if (startCal.getTimeInMillis() > endCal.getTimeInMillis()) {
			startCal.setTime(endDt);
			endCal.setTime(startDt);
		}

		do {
			startCal.add(Calendar.DAY_OF_MONTH, 1);
			if (isNotWeekend(startCal,weekend) && isNotHoliday(startCal, holiday)) {
				++workDays;
			}
		} while (startCal.getTimeInMillis() < endCal.getTimeInMillis());

		return workDays;
	}

	private boolean isNotWeekend(Calendar inputDate, List<Integer> weekend) {
		int dayOfWeek = inputDate.get(Calendar.DAY_OF_WEEK);
		for (int i = 0; i < weekend.size(); i++) {
			if (dayOfWeek == weekend.get(i).intValue()) {
				return false;
			}
		}
		return true;
	}
	
	private boolean isNotHoliday(Calendar inputDate, List<Date> holidays) {
		for (int i = 0; i < holidays.size(); i++) {
			Calendar holiday = Calendar.getInstance();
			holiday.setTime(holidays.get(i));
			if (inputDate.get(Calendar.YEAR) == holiday.get(Calendar.YEAR)
					&& inputDate.get(Calendar.MONTH) == holiday
							.get(Calendar.MONTH)
					&& inputDate.get(Calendar.DAY_OF_MONTH) == holiday
							.get(Calendar.DAY_OF_MONTH)) {
				return false;
			}
		}
		return true;
	}
}
